import { ref, computed, onMounted, onUnmounted, nextTick, type Ref } from 'vue'
import { useResponsive } from './useResponsive'
import { useVirtualKeyboard } from './useVirtualKeyboard'
import { useTouchGestures, enhanceTouchInteraction, expandTouchArea, type SwipeDirection } from './useTouchGestures'

export interface MobileInteractionOptions {
  enableSwipeGestures?: boolean
  enableVirtualKeyboard?: boolean
  optimizeTouchTargets?: boolean
  enableHapticFeedback?: boolean
  swipeThreshold?: number
  touchTargetMinSize?: number
}

/**
 * Enhanced mobile interaction composable that combines responsive design,
 * virtual keyboard handling, touch gestures, and mobile-specific optimizations
 */
export function useMobileInteraction(
  containerRef: Ref<HTMLElement | undefined>,
  options: MobileInteractionOptions = {}
) {
  const {
    enableSwipeGestures = true,
    enableVirtualKeyboard = true,
    optimizeTouchTargets = true,
    enableHapticFeedback = true,
    swipeThreshold = 50,
    touchTargetMinSize = 44
  } = options

  // Composables
  const responsive = useResponsive()
  const virtualKeyboard = enableVirtualKeyboard ? useVirtualKeyboard() : null
  const touchGestures = enableSwipeGestures ? useTouchGestures(containerRef, {
    swipeThreshold,
    preventScroll: false,
    enablePinch: false
  }) : null

  // Mobile interaction state
  const isInteracting = ref(false)
  const lastInteractionTime = ref(0)
  const interactionType = ref<'tap' | 'swipe' | 'scroll' | null>(null)

  // Touch target optimization
  const optimizedElements = ref<Set<HTMLElement>>(new Set())
  const expandedElements = ref<Map<HTMLElement, () => void>>(new Map())

  // Gesture callbacks
  const swipeCallbacks = ref<Map<string, (direction: SwipeDirection) => void>>(new Map())
  const tapCallbacks = ref<Map<string, (event: { x: number; y: number }) => void>>(new Map())

  // Computed properties
  const isMobileDevice = computed(() => responsive.isMobile.value && responsive.isTouchDevice.value)
  const shouldOptimizeForTouch = computed(() => responsive.isTouchDevice.value)
  const keyboardAdjustment = computed(() => {
    if (!virtualKeyboard || !virtualKeyboard.isKeyboardVisible.value) return 0
    return virtualKeyboard.keyboardHeight.value
  })

  // Methods for touch target optimization
  const optimizeTouchTarget = (element: HTMLElement, options: {
    minSize?: number
    hapticFeedback?: boolean
    preventDoubleClick?: boolean
  } = {}) => {
    if (!shouldOptimizeForTouch.value) return () => {}

    const cleanup = enhanceTouchInteraction(element, {
      minTouchSize: options.minSize || touchTargetMinSize,
      hapticFeedback: options.hapticFeedback ?? enableHapticFeedback,
      preventDoubleClick: options.preventDoubleClick ?? true,
      optimizeScrolling: true
    })

    optimizedElements.value.add(element)
    return cleanup
  }

  const expandTouchTarget = (element: HTMLElement, expansion = 8) => {
    if (!shouldOptimizeForTouch.value) return () => {}

    const cleanup = expandTouchArea(element, expansion)
    expandedElements.value.set(element, cleanup)
    return cleanup
  }

  // Gesture handling
  const onSwipe = (id: string, callback: (direction: SwipeDirection) => void) => {
    swipeCallbacks.value.set(id, callback)
    return () => {
      swipeCallbacks.value.delete(id)
    }
  }

  const onTap = (id: string, callback: (event: { x: number; y: number }) => void) => {
    tapCallbacks.value.set(id, callback)
    return () => {
      tapCallbacks.value.delete(id)
    }
  }

  // Virtual keyboard helpers
  const adjustForKeyboard = (element: HTMLElement, options?: {
    paddingBottom?: boolean
    translateY?: boolean
    maintainViewport?: boolean
  }) => {
    if (!virtualKeyboard) return
    virtualKeyboard.adjustForKeyboard(element, options)
  }

  const scrollIntoViewOnKeyboard = (element: HTMLElement, options?: {
    behavior?: ScrollBehavior
    block?: ScrollLogicalPosition
    offset?: number
  }) => {
    if (!virtualKeyboard) return
    virtualKeyboard.scrollIntoView(element, options)
  }

  const handleInputFocus = (inputElement: HTMLElement, options?: {
    scrollIntoView?: boolean
    adjustContainer?: HTMLElement
  }) => {
    if (!virtualKeyboard) return
    
    virtualKeyboard.handleInputFocus(inputElement, {
      scrollIntoView: options?.scrollIntoView,
      adjustContainer: options?.adjustContainer,
      adjustOptions: { paddingBottom: true }
    })
  }

  // Orientation change handling
  const orientationCallbacks = ref<(() => void)[]>([])
  
  const onOrientationChange = (callback: () => void) => {
    orientationCallbacks.value.push(callback)
    return responsive.onOrientationChange(callback)
  }

  // Interaction tracking
  const trackInteraction = (type: 'tap' | 'swipe' | 'scroll') => {
    isInteracting.value = true
    interactionType.value = type
    lastInteractionTime.value = Date.now()
    
    // Reset interaction state after delay
    setTimeout(() => {
      isInteracting.value = false
      interactionType.value = null
    }, 300)
  }

  // Safe area handling
  const applySafeAreaInsets = (element: HTMLElement, options: {
    top?: boolean
    bottom?: boolean
    left?: boolean
    right?: boolean
  } = {}) => {
    const { top = false, bottom = true, left = false, right = false } = options
    
    if (top) {
      element.style.paddingTop = `max(${element.style.paddingTop || '0px'}, env(safe-area-inset-top))`
    }
    if (bottom) {
      element.style.paddingBottom = `max(${element.style.paddingBottom || '0px'}, env(safe-area-inset-bottom))`
    }
    if (left) {
      element.style.paddingLeft = `max(${element.style.paddingLeft || '0px'}, env(safe-area-inset-left))`
    }
    if (right) {
      element.style.paddingRight = `max(${element.style.paddingRight || '0px'}, env(safe-area-inset-right))`
    }
  }

  // Prevent zoom on input focus (iOS)
  const preventInputZoom = (inputElement: HTMLInputElement | HTMLTextAreaElement) => {
    if (!virtualKeyboard) return () => {}
    return virtualKeyboard.preventZoomOnFocus(inputElement)
  }

  // Optimize scrolling performance
  const optimizeScrolling = (element: HTMLElement) => {
    if (!shouldOptimizeForTouch.value) return

    element.style.webkitOverflowScrolling = 'touch'
    element.style.overscrollBehavior = 'contain'
    element.style.scrollBehavior = 'smooth'
    
    // Add momentum scrolling for iOS
    if (/iPad|iPhone|iPod/.test(navigator.userAgent)) {
      element.style.webkitOverflowScrolling = 'touch'
    }
  }

  // Setup gesture listeners
  onMounted(() => {
    if (!touchGestures) return

    // Setup swipe handling
    const unsubscribeSwipe = touchGestures.onSwipe((swipe) => {
      trackInteraction('swipe')
      swipeCallbacks.value.forEach(callback => callback(swipe))
    })

    // Setup tap handling
    const unsubscribeTap = touchGestures.onTap((tap) => {
      trackInteraction('tap')
      tapCallbacks.value.forEach(callback => callback({ x: tap.x, y: tap.y }))
    })

    // Cleanup on unmount
    onUnmounted(() => {
      unsubscribeSwipe()
      unsubscribeTap()
      
      // Cleanup optimized elements
      optimizedElements.value.clear()
      expandedElements.value.forEach(cleanup => cleanup())
      expandedElements.value.clear()
    })
  })

  return {
    // Responsive state
    ...responsive,
    
    // Mobile-specific state
    isMobileDevice,
    shouldOptimizeForTouch,
    isInteracting,
    interactionType,
    lastInteractionTime,
    
    // Virtual keyboard
    keyboardState: virtualKeyboard?.keyboardState,
    isKeyboardVisible: virtualKeyboard?.isKeyboardVisible,
    keyboardHeight: virtualKeyboard?.keyboardHeight,
    keyboardAdjustment,
    
    // Touch gestures
    isTouch: touchGestures?.isTouch,
    touchDistance: touchGestures?.touchDistance,
    touchVelocity: touchGestures?.touchVelocity,
    
    // Methods
    optimizeTouchTarget,
    expandTouchTarget,
    onSwipe,
    onTap,
    onOrientationChange,
    adjustForKeyboard,
    scrollIntoViewOnKeyboard,
    handleInputFocus,
    applySafeAreaInsets,
    preventInputZoom,
    optimizeScrolling,
    trackInteraction
  }
}

// Utility functions for mobile optimization
export function isMobileUserAgent(): boolean {
  return /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
}

export function isIOSDevice(): boolean {
  return /iPad|iPhone|iPod/.test(navigator.userAgent)
}

export function isAndroidDevice(): boolean {
  return /Android/i.test(navigator.userAgent)
}

export function getDevicePixelRatio(): number {
  return window.devicePixelRatio || 1
}

export function getViewportSize() {
  return {
    width: window.innerWidth,
    height: window.innerHeight,
    availableWidth: window.screen.availWidth,
    availableHeight: window.screen.availHeight
  }
}

// CSS helper for mobile-optimized styles
export function getMobileOptimizedStyles() {
  return {
    // Prevent text selection on touch
    userSelect: 'none',
    webkitUserSelect: 'none',
    
    // Prevent callout on iOS
    webkitTouchCallout: 'none',
    
    // Remove tap highlight
    webkitTapHighlightColor: 'transparent',
    
    // Optimize touch scrolling
    webkitOverflowScrolling: 'touch',
    overscrollBehavior: 'contain',
    
    // Prevent zoom on double tap
    touchAction: 'manipulation',
    
    // Smooth scrolling
    scrollBehavior: 'smooth'
  }
}